"""
@author: xxw
@file: 06-进程之间共享数据.py
@time: 2023/6/27 15:09
"""
# 进程通信的方式:  管道、消息队列、信号量、共享内存、socket、信号

# 管道：一个内核缓冲区，先进先出
#     无名管道：父子进程，有亲缘关系的进程之间进行通信（没有亲缘关系，不知道管道位置在哪）
#     命名管道：无需确定亲缘关系也能通信

# 消息队列
#     内核中的消息列表，可以根据自己的情况读取特定的消息
# 共享内存     高效的进程通信方式
#     允许两个以上的进程通过映射共享内存区
#   ipcs -m     在linux中查看共享内存区
#   ipcrm       在linux中清除共享内存区
# 信号量   和共享内存搭配使用，允许最多多少个进程进行操作
    #P\V  操作
# 信号
# ctrl+c    ctrl+z    kill
# 关闭xshell连接，父进程会向子进程发送hup信号，子进程就退出了
# 要忽略hup信号，在运行之间命令前面加上nohup
# socket  套接字
#   可以用在不同主机之间的通信

# Manager
# from multiprocessing import Process, Manager, Lock
# import time
#
#
#
# def task(i, temp, lock):
#     with lock:
#         print("start......")
#         time.sleep(1)
#         temp[0] += 100
#         print(i, "---->", temp[0])
#
# if __name__ == "__main__":
#     m1 = Manager()
#     temp = m1.list([1, 2, 3])
#     p_list = []
#     lock = Lock()
#     for i in range(10):
#         p = Process(target=task, args=(i, temp, lock))
#         p.start()
#         p_list.append(p)
#
#     [p.join() for p in p_list]   #等待子进程运行完成 再往下运行
#                                  #父进程先退出的话，manager共享就没有用了
#     print("end......")

from multiprocessing import Process, Queue
import time

def task(i,q):
    if not q.empty(): #判断队列是否为空
        time.sleep(2)
        print(i, "--->get value", q.get())  #往队列中取数据

if __name__ == "__main__":
    q = Queue()
    for i in range(10):
        q.put(i)    #往队列里面放数据
        p = Process(target=task, args=(i, q))
        p.start()

# 进程安全  线程安全
# 队列 put 、 get 都是原子操作(要么成功，要么失败)